#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "consola_pfs.h"
#include "iniciarFat.h"
#include "cluster.h"
#include "colas.h"

	/* DAN: saqué los #define de generarConsola() y los puse como globales */




void generarConsola()
{

	#define MAX_LINE 250
	#define EXEC_OK 0xD7
	#define EXEC_FAIL 0xD8
	#define EXIT_OK 1
	#define EXIT_FAIL 0

	char *args[MAX_LINE/2+1];
    /****************************Comienzo de declaraciï¿½n variables*****************************/
	char *inputBuffer[MAX_LINE];
	int32_t iLectura, iBackground = 0, iEstado;
	/******************************Fin de declaraciï¿½n variables********************************/

	while(1) {
		printf("[PFS_Console]$ ");
		iLectura = fSetup(args, inputBuffer, &iBackground);
		if(iLectura) {
			printf("Error en los argumentos\n");
			continue;
		}
		else {
			if(args[0]!=NULL && strlen(args[0])>0) {

					iLectura = fValidaYEnviaCmds(args, inputBuffer);
			 }
		}
		fLiberaMem(args);
	}
}

int32_t fValidaYEnviaCmds(char *command[], char *inputBuffer){

	if(command[0]==NULL) return -1;

	if(strcmp(command[0],"fsinfo")==0) {

		/*
		 * Comando fsinfo
		 */

		pthread_mutex_lock(&mutexClustersLibres);
					printf("\nCantidad de clusters ocupados: %d\n",(bootSector->sectoresPorFat * (bootSector->bytesPorSector/4) )-clustersLibres->cantidadNodosLibres);
					printf("Cantidad de clusters libres: %d \n",clustersLibres->cantidadNodosLibres);
					pthread_mutex_unlock(&mutexClustersLibres);
					printf("Tamaño sector: %d bytes\n",bootSector->bytesPorSector);
					printf("Tamaño cluster: %d bytes\n",(bootSector->bytesPorSector* bootSector->sectoresPorCluster));
					printf("Tamaño FAT: %d Kb\n\n", bootSector->sectoresPorFat * bootSector->bytesPorSector / 1024 );


		return EXIT_OK;
	}
	else if (strcmp(command[0],"finfo")==0) {

		/*
		 * Comando finfo <path_archivo>
		 */

		char *nombre, *entrada;
		nombre = (char *) malloc (14);
		entrada = (char *) malloc (32);

		char esDirectorio;
		if (command[1] == NULL)
		{
			printf ("No ingresó un path.\n");
			return -1;
		}
		entrada = ObtenerEntradaDeArchivo(command[1], nombre, &esDirectorio);

		if (entrada == NULL) /* Devuelve 0 si es error, sino devuelve número de Cluster */
			{
				printf ("El archivo no existe, verifique el path ingresado.\n");
				return -1;
			}

		if (esDirectorio)
			{
				printf ("Es un directorio, verifique el path ingresado.\n");
				return -1;
			}

	uint32_t iClus = UbicacionCarpeta(entrada);
	uint32_t iClus2;

//		if(args[1] == NULL){
//			printf("Argumento invalido.\n");
//			return EXIT_FAIL;

	struct colaCluster *cola;
	struct cluster *st_clus;

	st_clus = (struct cluster *) malloc (sizeof(struct cluster));
	cola = (struct colaCluster *) malloc (sizeof(struct colaCluster));
	st_clus->numero = iClus;

	cola = CrearColaClusterDeEntradasDirectorio(st_clus); // El 2 es cluster de Raiz

	uint32_t cantNodosCola, i;
	cantNodosCola = CantidadDeNodosCola (cola);

	if (cola->frente->numero == 0)
	{
		printf("finfo	 %s /* Compuesto por %d cluster/s */\n\n", command[1], 0);
		printf("El archivo ocupa 0 bytes\n\n\n\n");
		return EXIT_OK;
	}

	printf("finfo	 %s /* Compuesto por %d cluster/s */\n\n", command[1], cantNodosCola);
	printf("#Clusters:\n\n");
	printf("(");
	for (i = 0; i < 20 && !ColaClusterVacia(*cola); i++)
	{
		iClus2 = SacarDeColaCluster(cola);
		printf("   %d", iClus2);
	}
		printf(").\n\n\n\n");
//		}

		return EXIT_OK;
	}else{
		printf("Comando no encontrado. Disponibles 'fsinfo' y 'finfo <filepath>' \n");
	}

	return EXIT_FAIL;

}

int32_t fSetup(char *args[], char *inputBuffer, int32_t *background)
	{
	int32_t i,j,k;
	int32_t num_args=0;

		args[num_args]=NULL;

		if(fLeeInput(inputBuffer, MAX_LINE)<0)
			return EXIT_FAIL;
		if(strlen(inputBuffer) == 0)
			return EXIT_FAIL;

		if(inputBuffer[strlen(inputBuffer)-1] == '&') {
			*background=1;
			inputBuffer[strlen(inputBuffer)-2]='\0';
		}

		for (i=0,j=0;i<strlen(inputBuffer);i++) {
			if(inputBuffer[i]==' ') {
				args[num_args] = (char *) malloc (sizeof(char)*(i-j+1));
				for (k=0;j<i;j++,k++) args[num_args][k] = inputBuffer[j];
				args[num_args][k]='\0';
				num_args++;
				j++;
				if(num_args > (MAX_LINE/2))
					return EXIT_FAIL;
			}
		}
		args[num_args] = (char *) malloc (sizeof(char)*(i-j+1));
		for (k=0;j<i;j++,k++) args[num_args][k] = inputBuffer[j];
		args[num_args][k]='\0';
		num_args++;

		inputBuffer[j++] = '\0';

		if(num_args > (MAX_LINE/2))
			return EXIT_FAIL;
		args[num_args] = NULL;
		return EXIT_FAIL;

	}


int32_t fLeeInput(char *buffer, int32_t MAX_BUFF_SIZE)
	{
		char c, previous;
		char *sp;

		sp=buffer;
		c=getchar();
		while(!isalpha(c) && !ispunct(c) && !isalnum(c) && c!='\n') { c=getchar(); }
		previous=c;
		while(c!='\n' && --MAX_BUFF_SIZE>0) {
			*sp++=c;
			c=getchar();
			if(previous==' ' && c ==' ') while((c=getchar())==' ') {}
			previous=c;
		}
		if(sp!=buffer)
			if (*(sp-1)==' ') *(sp-1)='\0'; else *sp='\0';
		else *sp='\0';
		return (c!='\n') ? -1 : sp-buffer;
	}


	void fLiberaMem(char *args[]){
		char **pArgs;

		pArgs=args;
		while(*pArgs!=NULL && *pArgs=="") {
			free(*pArgs);
			*pArgs = NULL;
			pArgs++;
		}
	}



